﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Diagnostics;
using CPPostsAnalyzerWP7.Models;
using System.Collections.ObjectModel;
using System.IO.IsolatedStorage;
using System.IO;
using System.Linq;
using Microsoft.Phone.Shell;
using System.Collections.Generic;

namespace CPPostsAnalyzerWP7.ViewModels
{
    public class MainViewModel : ViewModelBase
    {
        const string configPath = "CPPostsAnalyzerWP7\\recentmemberids.txt";

        public MainViewModel()
        {
            IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
            if (!store.FileExists(configPath))
                return;

            using (StreamReader reader = new StreamReader(new IsolatedStorageFileStream(configPath, FileMode.Open, store)))
            {
                var lines = reader.ReadToEnd().Trim().Split('\r', '\n').Where(s => !String.IsNullOrEmpty(s.Trim('\r', '\n'))).ToList();
                lines.ForEach(line => recentMemberIds.Add(line));
            }
        }

        public Dispatcher Dispatcher { get; internal set; }

        private string memberId;

        public string MemberId
        {
            get
            {
                return this.memberId;
            }

            set
            {
                if (this.memberId != value && value != null)
                {
                    this.memberId = value;
                    this.FirePropertyChanged("MemberId");
                }
            }
        }

        private string memberName;

        public string MemberName
        {
            get
            {
                return this.memberName;
            }

            set
            {
                if (this.memberName != value)
                {
                    this.memberName = value;
                    this.FirePropertyChanged("MemberName");
                }
            }
        }

        private bool canFetch = true;

        public bool CanFetch
        {
            get
            {
                return this.canFetch;
            }

            set
            {
                if (this.canFetch != value)
                {
                    this.canFetch = value;
                    this.FirePropertyChanged("CanFetch");
                }
            }
        }

        public void Fetch()
        {
            this.CanFetch = false;

            this.MemberName = String.Empty;
            results.Clear();
            forumTypeSummaries.Clear();
            postSummaries.Clear();

            PostsFetcher fetcher = new PostsFetcher(this.MemberId ?? String.Empty);
            fetcher.PostFetched += Fetcher_PostFetched;
            fetcher.FetchCompleted += Fetcher_FetchCompleted;
            fetcher.Fetch();            
        }

        public void SaveState()
        {
            var appService = PhoneApplicationService.Current;
            
            appService.State.Clear();

            appService.State["MemberId"] = this.MemberId;
            appService.State["CanFetch"] = this.CanFetch;
            
            if (this.CanFetch)
            {
                appService.State["MemberName"] = this.MemberName;
                appService.State["Results"] = this.Results;
                appService.State["ForumTypeSummaries"] = this.ForumTypeSummaries;
                appService.State["PostSummaries"] = this.PostSummaries;
            }
        }

        public void RetrieveState()
        {
            var appService = PhoneApplicationService.Current;

            if (appService.State.ContainsKey("MemberId"))
            {
                this.MemberId = (string)appService.State["MemberId"];
            }

            if (appService.State.ContainsKey("CanFetch"))
            {
                this.CanFetch = (bool)appService.State["CanFetch"];
            }

            if (!this.CanFetch)
            {
                this.CanFetch = true;
                return;
            }

            if (appService.State.ContainsKey("MemberName"))
            {
                this.MemberName = (string)appService.State["MemberName"];
            }

            if (appService.State.ContainsKey("Results"))
            {
                this.Results.Clear();

                foreach (PostInfo item in (IEnumerable<PostInfo>)appService.State["Results"])
                {
                    this.Results.Add(item);
                }
            }

            if (appService.State.ContainsKey("ForumTypeSummaries"))
            {
                this.ForumTypeSummaries.Clear();

                foreach (PostSummaryInfo item in (IEnumerable<PostSummaryInfo>)appService.State["ForumTypeSummaries"])
                {
                    this.ForumTypeSummaries.Add(item);
                }
            }

            if (appService.State.ContainsKey("PostSummaries"))
            {
                this.PostSummaries.Clear();

                foreach (PostSummaryInfo item in (IEnumerable<PostSummaryInfo>)appService.State["PostSummaries"])
                {
                    this.PostSummaries.Add(item);
                }
            }
        }

        private void Fetcher_FetchCompleted(object sender, FetchCompletedEventArgs e)
        {
            this.Dispatcher.BeginInvoke((Action)(() =>
            {
                if (e.Error == null)
                {
                    foreach (var item in e.ForumTypeSummaries)
                    {
                        forumTypeSummaries.Add(item);
                    }

                    foreach (var item in e.PostSummaries)
                    {
                        postSummaries.Add(item);
                    }

                    if (!recentMemberIds.Contains(this.MemberId))
                    {
                        if (recentMemberIds.Count == 10)
                        {
                            recentMemberIds.RemoveAt(9);
                        }

                        recentMemberIds.Insert(0, this.MemberId);

                        SaveConfig();
                    }
                }

               this.CanFetch = true;
            }));
        }

        private void SaveConfig()
        {
            IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
            string baseDirectory = System.IO.Path.GetDirectoryName(configPath);
            if (!store.DirectoryExists(baseDirectory))
            {
                store.CreateDirectory(baseDirectory);
            }

            using (StreamWriter writer = new StreamWriter(new IsolatedStorageFileStream(configPath, FileMode.Create, store)))
            {
                foreach (var entry in recentMemberIds)
                {
                    writer.WriteLine(entry);
                }
            }
        }

        private void Fetcher_PostFetched(object sender, PostInfoEventArgs e)
        {
            this.Dispatcher.BeginInvoke((Action)(() =>
            {
                results.Add(e.PostInfo);

                if(String.IsNullOrEmpty(this.MemberName))
                {
                    this.MemberName = e.PostInfo.DisplayName;
                }
            }));
        }

        ObservableCollection<PostInfo> results = new ObservableCollection<PostInfo>();

        public ObservableCollection<PostInfo> Results
        {
            get { return results; }
        }

        ObservableCollection<PostSummaryInfo> forumTypeSummaries = new ObservableCollection<PostSummaryInfo>();

        public ObservableCollection<PostSummaryInfo> ForumTypeSummaries
        {
            get { return forumTypeSummaries; }
        }

        ObservableCollection<PostSummaryInfo> postSummaries = new ObservableCollection<PostSummaryInfo>();

        public ObservableCollection<PostSummaryInfo> PostSummaries
        {
            get { return postSummaries; }
        }

        ObservableCollection<string> recentMemberIds = new ObservableCollection<string>();

        public ObservableCollection<string> RecentMemberIds
        {
            get { return recentMemberIds; }
        }
    }
}
